home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / xip / iijppp.lzh / Drivers / FreeBSD-1.1 / if_tun.c next >
C/C++ Source or Header  |  1994-10-03  |  12KB  |  569 lines

  1. /*
  2.  * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
  3.  * Nottingham University 1987.
  4.  *
  5.  * This source may be freely distributed, however I would be interested
  6.  * in any changes that are made.
  7.  *
  8.  * This driver takes packets off the IP i/f and hands them up to a
  9.  * user process to have it's wicked way with. This driver has it's
  10.  * roots in a similar driver written by Phil Cockcroft (formerly) at
  11.  * UCL. This driver is based much more on read/write/select mode of
  12.  * operation though.
  13.  * 
  14.  * $Id: if_tun.c,v 1.9 1993/12/24 03:20:59 deraadt Exp $
  15.  */
  16.  
  17. #include "tun.h"
  18. #if NTUN > 0
  19.  
  20. #include "param.h"
  21. #include "kernel.h"        /* sigh */
  22. #include "proc.h"
  23. #include "systm.h"
  24. #include "mbuf.h"
  25. #include "buf.h"
  26. #include "protosw.h"
  27. #include "socket.h"
  28. #include "ioctl.h"
  29. #include "errno.h"
  30. #include "syslog.h"
  31. #include <sys/file.h>
  32.  
  33. #include <machine/cpu.h>
  34.  
  35. #include <net/if.h>
  36. #include <net/netisr.h>
  37. #include <net/route.h>
  38.  
  39. #ifdef INET
  40. #include <netinet/in.h>
  41. #include <netinet/in_systm.h>
  42. #include <netinet/in_var.h>
  43. #include <netinet/ip.h>
  44. #include <netinet/if_ether.h>
  45. #endif
  46.  
  47. #ifdef NS
  48. #include <netns/ns.h>
  49. #include <netns/ns_if.h>
  50. #endif
  51.  
  52. #include "bpfilter.h"
  53. #if NBPFILTER > 0
  54. #include <sys/time.h>
  55. #include <net/bpf.h>
  56. #endif
  57.  
  58. #include <net/if_tun.h>
  59.  
  60. #define TUNDEBUG    if (tundebug) printf
  61. int    tundebug = 0;
  62.  
  63. struct tun_softc tunctl[NTUN];
  64. extern int ifqmaxlen;
  65.  
  66. int    tunopen __P((int, int, int, struct proc *));
  67. int    tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *rt));
  68. int    tunselect __P((int dev, int, struct proc *));
  69. int    tunifioctl __P((struct ifnet *, int, caddr_t));
  70. int    tunioctl __P((int, int, caddr_t, int));
  71.  
  72. static int tuninit __P((int));
  73.  
  74. void
  75. tunattach(void)
  76. {
  77.     register int i;
  78.     struct ifnet *ifp;
  79.     struct sockaddr_in *sin;
  80.  
  81.     for (i = 0; i < NTUN; i++) {
  82.         tunctl[i].tun_flags = TUN_INITED;
  83.  
  84.         ifp = &tunctl[i].tun_if;
  85.         ifp->if_unit = i;
  86.         ifp->if_name = "tun";
  87.         ifp->if_mtu = TUNMTU;
  88.         ifp->if_ioctl = tunifioctl;
  89.         ifp->if_output = tunoutput;
  90.         ifp->if_flags = IFF_POINTOPOINT;
  91.         ifp->if_snd.ifq_maxlen = ifqmaxlen;
  92.         ifp->if_collisions = 0;
  93.         ifp->if_ierrors = 0;
  94.         ifp->if_oerrors = 0;
  95.         ifp->if_ipackets = 0;
  96.         ifp->if_opackets = 0;
  97.         if_attach(ifp);
  98. #if NBPFILTER > 0
  99.         bpfattach(&tunctl[i].tun_bpf, ifp, DLT_NULL, sizeof(u_int));
  100. #endif
  101.     }
  102. }
  103.  
  104. TEXT_SET(pseudo_set, tunattach);
  105.  
  106. /*
  107.  * tunnel open - must be superuser & the device must be
  108.  * configured in
  109.  */
  110. int
  111. tunopen(dev, flag, mode, p)
  112.     dev_t    dev;
  113.     int    flag, mode;
  114.     struct proc *p;
  115. {
  116.     struct ifnet    *ifp;
  117.     struct tun_softc *tp;
  118.     register int    unit, error;
  119.  
  120.     if (error = suser(p->p_ucred, &p->p_acflag))
  121.         return (error);
  122.  
  123.     if ((unit = minor(dev)) >= NTUN)
  124.         return (ENXIO);
  125.     tp = &tunctl[unit];
  126.     if (tp->tun_flags & TUN_OPEN)
  127.         return ENXIO;
  128.     ifp = &tp->tun_if;
  129.     tp->tun_flags |= TUN_OPEN;
  130.     TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
  131.     return (0);
  132. }
  133.  
  134. /*
  135.  * tunclose - close the device - mark i/f down & delete
  136.  * routing info
  137.  */
  138. int
  139. tunclose(dev, flag)
  140.     dev_t    dev;
  141.     int    flag;
  142. {
  143.     register int    unit = minor(dev), s;
  144.     struct tun_softc *tp = &tunctl[unit];
  145.     struct ifnet    *ifp = &tp->tun_if;
  146.     struct mbuf    *m;
  147.     int    rcoll;
  148.  
  149.     rcoll = tp->tun_flags & TUN_RCOLL;
  150.     tp->tun_flags &= ~TUN_OPEN;
  151.  
  152.     /*
  153.      * junk all pending output
  154.      */
  155.     do {
  156.         s = splimp();
  157.         IF_DEQUEUE(&ifp->if_snd, m);
  158.         splx(s);
  159.         if (m)
  160.             m_freem(m);
  161.     } while (m);
  162.  
  163.     if (ifp->if_flags & IFF_UP) {
  164.         s = splimp();
  165.         if_down(ifp);
  166. #ifdef notdef
  167.         if (ifp->if_flags & IFF_RUNNING) {
  168.             rtinit(ifp->if_addrlist, (int)RTM_DELETE,
  169.                    tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
  170.         }
  171. #endif
  172.         splx(s);
  173.     }
  174.     tp->tun_pgrp = 0;
  175.     if (tp->tun_rsel)
  176.       selwakeup(tp->tun_rsel->p_pid, rcoll);
  177.         tp -> tun_rsel = tp -> tun_wsel = (struct proc *)0;
  178.         
  179.     TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
  180.     return (0);
  181. }
  182.  
  183. static int
  184. tuninit(unit)
  185.     int    unit;
  186. {
  187.     struct tun_softc *tp = &tunctl[unit];
  188.     struct ifnet    *ifp = &tp->tun_if;
  189.     register struct ifaddr *ifa;
  190.  
  191.     TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
  192.  
  193.     ifp->if_flags |= IFF_UP | IFF_RUNNING;
  194.  
  195.     for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
  196.         struct sockaddr_in *si;
  197.  
  198.         si = (struct sockaddr_in *)ifa->ifa_addr;
  199.         if (si && si->sin_addr.s_addr)
  200.             tp->tun_flags |= TUN_IASET;
  201.  
  202.         si = (struct sockaddr_in *)ifa->ifa_dstaddr;
  203.         if (si && si->sin_addr.s_addr)
  204.             tp->tun_flags |= TUN_DSTADDR;
  205.     }
  206.  
  207.     return 0;
  208. }
  209.  
  210. /*
  211.  * Process an ioctl request.
  212.  */
  213. int
  214. tunifioctl(ifp, cmd, data)
  215.     struct ifnet *ifp;
  216.     int    cmd;
  217.     caddr_t    data;
  218. {
  219.     struct tun_softc *tp = &tunctl[ifp->if_unit];
  220.     int        error = 0, s;
  221.  
  222.     s = splimp();
  223.     switch(cmd) {
  224.     case SIOCSIFADDR:
  225.         tuninit(ifp->if_unit);
  226.         break;
  227.     case SIOCSIFDSTADDR:
  228.         tp->tun_flags |= TUN_DSTADDR;
  229.         TUNDEBUG("%s%d: destination address set\n", ifp->if_name,
  230.             ifp->if_unit);
  231.         break;
  232.     default:
  233.         error = EINVAL;
  234.     }
  235.     splx(s);
  236.     return (error);
  237. }
  238.  
  239. /*
  240.  * tunoutput - queue packets from higher level ready to put out.
  241.  */
  242. int
  243. tunoutput(ifp, m0, dst, rt)
  244.     struct ifnet   *ifp;
  245.     struct mbuf    *m0;
  246.     struct sockaddr *dst;
  247.     struct rtentry *rt;
  248. {
  249.     struct tun_softc *tp = &tunctl[ifp->if_unit];
  250.     struct proc    *p;
  251.     int        s;
  252.  
  253.     TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
  254.  
  255.     if ((tp->tun_flags & TUN_READY) != TUN_READY) {
  256.         TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
  257.               ifp->if_unit, tp->tun_flags);
  258.         m_freem (m0);
  259.         return EHOSTDOWN;
  260.     }
  261.  
  262. #if NBPFILTER > 0
  263.     if (tp->tun_bpf) {
  264.         /*
  265.          * We need to prepend the address family as
  266.          * a four byte field.  Cons up a dummy header
  267.          * to pacify bpf.  This is safe because bpf
  268.          * will only read from the mbuf (i.e., it won't
  269.          * try to free it or keep a pointer to it).
  270.          */
  271.         struct mbuf m;
  272.         u_int af = dst->sa_family;
  273.  
  274.         m.m_next = m0;
  275.         m.m_len = 4;
  276.         m.m_data = (char *)⁡
  277.  
  278.         bpf_mtap(tp->tun_bpf, &m);
  279.     }
  280. #endif
  281.  
  282.     switch(dst->sa_family) {
  283. #ifdef INET
  284.     case AF_INET:
  285.         s = splimp();
  286.         if (IF_QFULL(&ifp->if_snd)) {
  287.             IF_DROP(&ifp->if_snd);
  288.             m_freem(m0);
  289.             splx(s);
  290.             ifp->if_collisions++;
  291.             return (ENOBUFS);
  292.         }
  293.         IF_ENQUEUE(&ifp->if_snd, m0);
  294.         splx(s);
  295.         ifp->if_opackets++;
  296.         break;
  297. #endif
  298.     default:
  299.         m_freem(m0);
  300.         return EAFNOSUPPORT;
  301.     }
  302.  
  303.     if (tp->tun_flags & TUN_RWAIT) {
  304.         tp->tun_flags &= ~TUN_RWAIT;
  305.         wakeup((caddr_t)tp);
  306.     }
  307.     if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
  308.         if (tp->tun_pgrp > 0)
  309.             gsignal(tp->tun_pgrp, SIGIO);
  310.         else if (p = pfind(-tp->tun_pgrp))
  311.             psignal(p, SIGIO);
  312.     }
  313.     if (tp->tun_rsel) {
  314.       selwakeup(tp->tun_rsel->p_pid, tp->tun_flags & TUN_RCOLL);
  315.       tp->tun_flags &= ~TUN_RCOLL;
  316.       tp->tun_rsel = (struct proc *)0;
  317.     }
  318.     return 0;
  319. }
  320.  
  321. /*
  322.  * the cdevsw interface is now pretty minimal.
  323.  */
  324. int
  325. tunioctl(dev, cmd, data, flag)
  326.     dev_t        dev;
  327.     int        cmd;
  328.     caddr_t        data;
  329.     int        flag;
  330. {
  331.     int        unit = minor(dev), s;
  332.     struct tun_softc *tp = &tunctl[unit];
  333.     struct tuninfo *tunp;
  334.  
  335.     switch (cmd) {
  336.     case TUNSIFINFO:
  337.             tunp = (struct tuninfo *)data;
  338.         tp->tun_if.if_mtu = tunp->if_mtu;
  339.         tp->tun_if.if_type = tunp->if_type;
  340.         tp->tun_if.if_baudrate = tunp->if_baudrate;
  341.         break;
  342.     case TUNGIFINFO:
  343.         tunp = (struct tuninfo *)data;
  344.         tunp->if_mtu = tp->tun_if.if_mtu;
  345.         tunp->if_type = tp->tun_if.if_type;
  346.         tunp->if_baudrate = tp->tun_if.if_baudrate;
  347.         break;
  348.     case TUNSDEBUG:
  349.         tundebug = *(int *)data;
  350.         break;
  351.     case TUNGDEBUG:
  352.         *(int *)data = tundebug;
  353.         break;
  354.     case FIONBIO:
  355.         if (*(int *)data)
  356.             tp->tun_flags |= TUN_NBIO;
  357.         else
  358.             tp->tun_flags &= ~TUN_NBIO;
  359.         break;
  360.     case FIOASYNC:
  361.         if (*(int *)data)
  362.             tp->tun_flags |= TUN_ASYNC;
  363.         else
  364.             tp->tun_flags &= ~TUN_ASYNC;
  365.         break;
  366.     case FIONREAD:
  367.         s = splimp();
  368.         if (tp->tun_if.if_snd.ifq_head)
  369.             *(int *)data = tp->tun_if.if_snd.ifq_head->m_len;
  370.         else    
  371.             *(int *)data = 0;
  372.         splx(s);
  373.         break;
  374.     case TIOCSPGRP:
  375.         tp->tun_pgrp = *(int *)data;
  376.         break;
  377.     case TIOCGPGRP:
  378.         *(int *)data = tp->tun_pgrp;
  379.         break;
  380.     default:
  381.         return (ENOTTY);
  382.     }
  383.     return (0);
  384. }
  385.  
  386. /*
  387.  * The cdevsw read interface - reads a packet at a time, or at
  388.  * least as much of a packet as can be read.
  389.  */
  390. int
  391. tunread(dev, uio)
  392.     dev_t        dev;
  393.     struct uio    *uio;
  394. {
  395.     int        unit = minor(dev);
  396.     struct tun_softc *tp = &tunctl[unit];
  397.     struct ifnet    *ifp = &tp->tun_if;
  398.     struct mbuf    *m, *m0;
  399.     int        error=0, len, s;
  400.  
  401.     TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
  402.     if ((tp->tun_flags & TUN_READY) != TUN_READY) {
  403.         TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
  404.               ifp->if_unit, tp->tun_flags);
  405.         return EHOSTDOWN;
  406.     }
  407.  
  408.     tp->tun_flags &= ~TUN_RWAIT;
  409.  
  410.     s = splimp();
  411.     do {
  412.         IF_DEQUEUE(&ifp->if_snd, m0);
  413.         if (m0 == 0) {
  414.             if (tp->tun_flags & TUN_NBIO) {
  415.                 splx(s);
  416.                 return EWOULDBLOCK;
  417.             }
  418.             tp->tun_flags |= TUN_RWAIT;
  419.             tsleep((caddr_t)tp, PZERO + 1, "tunread", 0);
  420.         }
  421.     } while (m0 == 0);
  422.     splx(s);
  423.  
  424.     while (m0 && uio->uio_resid > 0 && error == 0) {
  425.         len = MIN(uio->uio_resid, m0->m_len);
  426.         if (len == 0)
  427.             break;
  428.         error = uiomove(mtod(m0, caddr_t), len, uio);
  429.         MFREE(m0, m);
  430.         m0 = m;
  431.     }
  432.  
  433.     if (m0) {
  434.         TUNDEBUG("Dropping mbuf\n");
  435.         m_freem(m0);
  436.     }
  437.     return error;
  438. }
  439.  
  440. /*
  441.  * the cdevsw write interface - an atomic write is a packet - or else!
  442.  */
  443. int
  444. tunwrite(dev, uio)
  445.     dev_t        dev;
  446.     struct uio    *uio;
  447. {
  448.     int        unit = minor (dev);
  449.     struct ifnet    *ifp = &tunctl[unit].tun_if;
  450.     struct mbuf    *top, **mp, *m;
  451.     int        error=0, s, tlen, mlen;
  452.  
  453.     TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
  454.  
  455.     if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) {
  456.         TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
  457.             uio->uio_resid);
  458.         return EIO;
  459.     }
  460.     tlen = uio->uio_resid;
  461.  
  462.     /* get a header mbuf */
  463.     MGETHDR(m, M_DONTWAIT, MT_DATA);
  464.     if (m == NULL)
  465.         return ENOBUFS;
  466.     mlen = MHLEN;
  467.  
  468.     top = 0;
  469.     mp = ⊤
  470.     while (error == 0 && uio->uio_resid > 0) {
  471.         m->m_len = MIN (mlen, uio->uio_resid);
  472.         error = uiomove(mtod (m, caddr_t), m->m_len, uio);
  473.         *mp = m;
  474.         mp = &m->m_next;
  475.         if (uio->uio_resid > 0) {
  476.             MGET (m, M_DONTWAIT, MT_DATA);
  477.             if (m == 0) {
  478.                 error = ENOBUFS;
  479.                 break;
  480.             }
  481.             mlen = MLEN;
  482.         }
  483.     }
  484.     if (error) {
  485.         if (top)
  486.             m_freem (top);
  487.         return error;
  488.     }
  489.  
  490.     top->m_pkthdr.len = tlen;
  491.     top->m_pkthdr.rcvif = ifp;
  492.  
  493. #if NBPFILTER > 0
  494.     if (tunctl[unit].tun_bpf) {
  495.         /*
  496.          * We need to prepend the address family as
  497.          * a four byte field.  Cons up a dummy header
  498.          * to pacify bpf.  This is safe because bpf
  499.          * will only read from the mbuf (i.e., it won't
  500.          * try to free it or keep a pointer to it).
  501.          */
  502.         struct mbuf m;
  503.         u_int af = AF_INET;
  504.  
  505.         m.m_next = top;
  506.         m.m_len = 4;
  507.         m.m_data = (char *)⁡
  508.  
  509.         bpf_mtap(tunctl[unit].tun_bpf, &m);
  510.     }
  511. #endif
  512.  
  513.     s = splimp();
  514.     if (IF_QFULL (&ipintrq)) {
  515.         IF_DROP(&ipintrq);
  516.         splx(s);
  517.         ifp->if_collisions++;
  518.         m_freem(top);
  519.         return ENOBUFS;
  520.     }
  521.     IF_ENQUEUE(&ipintrq, top);
  522.     splx(s);
  523.     ifp->if_ipackets++;
  524.     schednetisr(NETISR_IP);
  525.     return error;
  526. }
  527.  
  528. /*
  529.  * tunselect - the select interface, this is only useful on reads
  530.  * really. The write detect always returns true, write never blocks
  531.  * anyway, it either accepts the packet or drops it.
  532.  */
  533. int
  534. tunselect(dev, rw, p)
  535.     dev_t        dev;
  536.     int        rw;
  537.     struct proc    *p;
  538. {
  539.     int        unit = minor(dev), s;
  540.     struct tun_softc *tp = &tunctl[unit];
  541.     struct ifnet    *ifp = &tp->tun_if;
  542.  
  543.     s = splimp();
  544.     TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit);
  545.  
  546.     switch (rw) {
  547.     case FREAD:
  548.         if (ifp->if_snd.ifq_len > 0) {
  549.             splx(s);
  550.             TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name,
  551.                 ifp->if_unit, ifp->if_snd.ifq_len);
  552.             return 1;
  553.         }
  554.         if (tp->tun_rsel && tp->tun_rsel == p)
  555.             tp->tun_flags |= TUN_RCOLL;
  556.         else
  557.             tp->tun_rsel = p;
  558.         break;
  559.     case FWRITE:
  560.         splx(s);
  561.         return 1;
  562.     }
  563.     splx(s);
  564.     TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit);
  565.     return 0;
  566. }
  567.  
  568. #endif  /* NTUN */
  569.